package com.ywy.controller;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.ywy.common.rest.Result;
import com.ywy.config.RabbitMqConfig;
import com.ywy.entity.Category;
import com.ywy.entity.Post;
import com.ywy.search.mq.MqPostMessage;
import com.ywy.service.*;
import com.ywy.utils.ValidationUtil;
import com.ywy.vo.PostVo;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 博客文章 前端控制器
 * </p>
 *
 * @author ywy
 * @since 2021-12-24
 */
@Controller
@RequestMapping("/post")
public class PostController extends BaseController {
    @Autowired
    private PostService postService;
    @Autowired
    private CategoryService categoryService;
    @Autowired
    private CommentService commentService;
    @Autowired
    private UserMessageService userMessageService;
    @Autowired
    private UserCollectionService userCollectionService;
    @Autowired
    private AmqpTemplate amqpTemplate;

    /**
     * 博客详情
     * @param id
     * @return
     */
    @GetMapping("/{id:\\d*}")
    public String detail(@PathVariable Integer id) {
        // 根据id查询博客文章详细信息
        PostVo post = postService.getDetail(id);
        Assert.notNull(post, "该文章已被删除");

        // 分页查询博客评论信息
        IPage comments = commentService.listByPage(getPage(), post.getId(), null, "create_time");

        // 修改文章阅读量
        postService.updateViewCount(post);

        req.setAttribute("currentCategoryId", post.getCategoryId());
        req.setAttribute("post", post);
        req.setAttribute("comments", comments);
        return "post/detail";
    }

    /**
     * 跳转博客文章编辑页面
     * @return
     */
    @GetMapping("/edit")
    public String edit() {
        String id = req.getParameter("id");
        if (!StringUtils.isEmpty(id)) {
            // 查询文章
            Post post = postService.getById(id);
            Assert.notNull(post, "该文章已被删除");
            // 判断文章是否是登录用户的
            Assert.isTrue(post.getUserId().equals(getProfileId()), "没有权限编辑此文章");
            req.setAttribute("post", post);
        }

        List<Category> categories = categoryService.list();
        req.setAttribute("categories", categories);

        return "post/edit";
    }

    /**
     * 添加或修改博客文章
     * @param post
     * @return
     */
    @ResponseBody
    @PostMapping("/edit")
    public Result edit(Post post) {
        // 校验参数
        ValidationUtil.ValidResult validResult = ValidationUtil.validateBean(post);
        if (validResult.isHasErrors()) {
            return Result.failure(validResult.getAllErrors());
        }
        // 添加文章
        if (post.getId() == null) {
            post.setUserId(getProfileId());
            postService.save(post);
        } else {
            // 编辑文章
            Post tempPost = postService.getById(post.getId());
            // 编辑时判断是否是自己的文章
            Assert.isTrue(tempPost.getUserId().equals(getProfileId()), "没有权限编辑此文章");
            tempPost.setTitle(post.getTitle());
            tempPost.setContent(post.getContent());
            tempPost.setCategoryId(post.getCategoryId());
            postService.updateById(tempPost);
        }

        // 通知消息给mq，异步添加或更新ES索引
        amqpTemplate.convertAndSend(RabbitMqConfig.ES_EXCHANGE, RabbitMqConfig.ES_BIND_KEY,
                new MqPostMessage(post.getId(), MqPostMessage.CREATE_OR_UPDATE));
        return Result.success("/post/" + post.getId());
    }

    /**
     * 删除博客文章
     * @param id
     * @return
     */
    @Transactional
    @ResponseBody
    @PostMapping("/delete")
    public Result delete(Integer id) {
        Post post = postService.getById(id);
        Assert.notNull(post, "该文章已被删除");
        // 当前用户不是管理员则只能删除自己的文章
        Subject subject = SecurityUtils.getSubject();
        if(!subject.hasRole("admin")) {
            Assert.isTrue(post.getUserId().equals(getProfileId()), "没有权限删除此文章");
        }

        postService.removeById(id);

        // 删除相关消息、收藏等
        Map<String, Object> columnMap = new HashMap<>();
        columnMap.put("post_id", id);
        userMessageService.removeByMap(columnMap);
        userCollectionService.removeByMap(columnMap);

        // 通知消息给mq，异步删除ES索引
        amqpTemplate.convertAndSend(RabbitMqConfig.ES_EXCHANGE, RabbitMqConfig.ES_BIND_KEY,
                new MqPostMessage(post.getId(), MqPostMessage.REMOVE));
        return Result.success("/user/index");
    }

    /**
     * 设置置顶、加精操作
     * @param id
     * @param status 0：取消；1：操作
     * @param field level：置顶操作；recommend：加精操作
     * @return
     */
    @ResponseBody
    @PostMapping("/set")
    public Result set(Long id, Integer status, String field) {
        Post post = postService.getById(id);
        Assert.notNull(post, "该帖子已被删除");

        if("recommend".equals(field)) {
            post.setRecommend(status == 1);
        }  else if("level".equals(field)) {
            post.setLevel(status);
        }
        postService.updateById(post);
        return Result.success();
    }

}
